package leetcode;

import java.util.Arrays;
import java.util.Scanner;


//寻找a[i] * a[j] * (a[i] & a[j])的最大值
public class FindMultipleMax {

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		int testCase = scanner.nextInt();
		int numberCount;
		int[] numbers;
		for (int i = 0; i < testCase; i++) {
			numberCount = scanner.nextInt();
			numbers = new int[numberCount];
			for(int j = 0; j < numberCount; j++){
				numbers[j] = scanner.nextInt();
			}
			getMaxValue3(numbers);
		}
		scanner.close();
	}
	
	//先暴力来一遍
	//超时 19573ms
	public static void getMaxValue(int[] arr){
		long max = 0;
		long res = 1;
		
		for (int i = 0; i < arr.length; i++) {
			for (int j = i + 1; j < arr.length; j++) {
				res = 1;
				long and = arr[i] & arr[j];
				and *= arr[i];
				res = and * arr[j];
				if(res > max){
					max = res;
				}
			}
		}
		System.out.println(max);
	}
	
	//使用贪心来一遍试试
	//贪心策略：求最大的两个数
	//然后求最大的数 与所有的数得到的max(arr[i] & arr[j])
	//还有就是max(arr[i] & arr[j] 
	public static void getMaxValue2(int[] arr){
		int maxValue = 0;
		int secondValue = 0;;
		for (int i = 0; i < arr.length; i++) {
			if(arr[i] > maxValue){
				secondValue = maxValue;
				maxValue = secondValue;
			}else if(arr[i] == maxValue){
				secondValue = arr[i];
			}else if(arr[i] > secondValue){
				secondValue = arr[i];
			}
		}
		
		int maxAnd;	//获取最大的两个数相与的结果
		int maxAndWithMaxValue;	//获取与maxValue相与最大的值
		
		for (int i = 0; i < arr.length; i++) {
			//那么问题来了，怎么在O(n)的时间内知道两个数相与的最大值呢
			//HDU 4825是一道用前缀树实现的求最两两亦或的最大值
			//让我们看看能否实现
			
			//先留坑，不知道能否实现，2017/04/04 21 ：07
		}
	}
	
	//第三种实现，排序后然后相乘
	//AC	5684ms
	public static void getMaxValue3(int[] arr){
		//首先进行排序
		Arrays.sort(arr);
		long max = 0;
		
		for (int i = arr.length - 1; i >= 0; i--) {
			for (int j = i - 1; j >= 0; j--) {
				long temp = arr[i];
				temp *= arr[j];
				//因为arr[i] >= arr[j],所以(arr[i] & arr[j]) <= arr[i]
				if(temp * arr[i] < max){
					break;
				}
				temp *= (arr[i] & arr[j]);
				if(temp > max){
					max = temp;
				}
			}
		}
		System.out.println(max);
	}
	
	private class TrieNode{
		//path表示有多少个数共用这个结点
		public int path;
		public TrieNode[] child;
		//只有0，1
		public TrieNode() {
			path = 0;
			//这里假定只包含26个字母的
			child = new TrieNode[2];
		}
	}
	
	public void add(int x, TrieNode root){
		for(int i = 31; i >= 0; i--){  
	        int bit = (x >> i) & 1;  
	        if(root.child[bit] == null){
	        	root.child[bit] = new TrieNode();  
	        }
	        root = root.child[bit];
	        root.path++;
	    }
	}
	
	public int search(int x, TrieNode root){  
	    int ans = 0;  
	    for(int i = 31; i >= 0; i--){  
	        int bit = (x >> i) & 1;  
	        ans = ans << 1;  
	        //root.path > 1表示的是最少有两个数公用该结点
	        if(root.child[1] != null && root.path > 1){
	        	ans += bit;
	        	root = root.child[bit];  
	        }else {
	        	root = root.child[~bit];  
	        }
	    }      
	    return ans;  
	}  
}
